﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Windows;
using TwinCAT.Ads;

namespace Enterprises.Wpf.Sample.ViewModel
{
    /// <summary>
    /// TwinCat 简单轴运动控制.
    /// </summary>
    public partial class TwinCatSimpleMotionDemoCtlViewModel : ObservableObject
    {
        /// <summary>
        /// TcAdsClient
        /// </summary>
        private TcAdsClient tcClient;
        private Timer timer;

        private int positionHandle;
        private int powerHandle;
        private int targetPosHandle;
        private int valocityHandle;
        private int moveToHandle;
        private int readHandle;

        /// <summary>
        /// 构造函数.
        /// </summary>
        public TwinCatSimpleMotionDemoCtlViewModel()
        {
        }

        /// <summary>
        /// 获取当前轴位置.
        /// </summary>
        /// <param name="state"></param>
        private void GetPostion(object? state)
        {
            // 读取当前位置
            Application.Current.Dispatcher.Invoke(() =>
            {
                var pos = tcClient.ReadAny(positionHandle, typeof(double)).ToString();
                if (double.TryParse(pos, out var outPos))
                {
                    Postion = outPos;
                }
            });
        }


        /// <summary>
        /// 当前位置.
        /// </summary>
        [ObservableProperty]
        private double postion;

        /// <summary>
        /// 目标位置.
        /// </summary>
        [ObservableProperty]
        private double targetPosition = 2600;

        /// <summary>
        /// 速度.
        /// </summary>
        [ObservableProperty]
        private float velocity = 50;

        /// <summary>
        /// 使能按钮文字.
        /// </summary>
        [ObservableProperty]
        private string powerDesc = "开使能";

        [ObservableProperty]
        [NotifyCanExecuteChangedFor(nameof(MovePosCommand))]
        private bool isPowered = false;

        /// <summary>
        /// 上使能
        /// </summary>
        [RelayCommand]
        private void Power()
        {
            // 创建Ads Client,默认本机IP地址
            tcClient = new TcAdsClient();
            tcClient.Connect(851);

            // 定义变量寻址地址，POU.position 前面为POUs类目，后面为变量
            positionHandle = tcClient.CreateVariableHandle("POU.position");
            powerHandle = tcClient.CreateVariableHandle("POU.Test_PowerDo");
            targetPosHandle = tcClient.CreateVariableHandle("POU.Test_Position");
            valocityHandle = tcClient.CreateVariableHandle("POU.Test_Velocity");
            moveToHandle = tcClient.CreateVariableHandle("POU.Test_PositionDo");
            readHandle = tcClient.CreateVariableHandle("POU.Test_ReadDo");

            // 设置Test_ReadDo=true
            tcClient.WriteAny(readHandle, true);
            timer = new Timer(GetPostion, null, -1, 0);

            if (PowerDesc == "开使能")
            {
                IsPowered = true;
                PowerDesc = "关使能";
                timer.Change(0, 50);
            }
            else
            {
                IsPowered = false;
                PowerDesc = "开使能";
                timer.Change(-1, 0);
            }

            tcClient.WriteAny(powerHandle, IsPowered);
        }

        /// <summary>
        /// 启动绝对值运动
        /// </summary>
        [RelayCommand(CanExecute = nameof(IsPowered))]

        private async Task MovePosAsync()
        {
            // 赋值类型一定要准确，比如REAL类型，赋值doubel 会异常.
            tcClient.WriteAny(moveToHandle, false);
            tcClient.WriteAny(targetPosHandle, TargetPosition);
            tcClient.WriteAny(valocityHandle, Velocity);
            await Task.Delay(50);
            tcClient.WriteAny(moveToHandle, true);
        }
    }
}
